package com.wxq.workpad.utils;

import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author: tw
 * @date: 2021/7/5 0005 14:55
 * @email：2278671454@qq.com
 * @description: Device工具类
 * PS：此方法内的测试机为友盟上的华为以及VIVO手机，以及公司测试机华为平板（支持虚拟按键或刘海屏的）
 * 由于不想影响到原先使用处，故获取方法保留，具体使用参照方法注释
 */
public class DeviceUtils {

    private static final String TAG = "DeviceUtils";

    /**
     * @return int 实际转换后的px值
     * @description: 单位转换：dp转px
     */
    public static int dp2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 将px值转换为dip或dp值，保证尺寸大小不变
     *
     * @param pxValue （DisplayMetrics类中属性density）
     * @return 实际转换后的dp值
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    public static int px2dip(Context context, float pxValue, float density) {
        return (int) (pxValue / density + 0.5f);
    }

    /**
     * 将sp值转换为px值，保证文字大小不变
     *
     * @param spValue （DisplayMetrics类中属性scaledDensity）
     * @return 实际转换后的px值
     */
    public static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    /**
     * 获取屏幕真实高度
     * 此方法获取的高度为包含虚拟导航按键的高度，即使在虚拟导航栏被隐藏的情况下
     *
     * @param activity 当前activity
     * @return
     */
    public static Pair<Integer, Integer> getScreenRealSize(Activity activity) {
        Pair<Integer, Integer> commonSize = getScreenSize(activity);
        int realWidth = commonSize.first;
        int realHeight = commonSize.second;
        Display display = activity.getWindowManager().getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        @SuppressWarnings("rawtypes")
        Class c;
        try {
            c = Class.forName("android.view.Display");
            @SuppressWarnings("unchecked")
            Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
            method.invoke(display, dm);
            realWidth = dm.widthPixels;
            realHeight = dm.heightPixels;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Pair<>(realWidth, realHeight);
    }

    /**
     * 使用普通的方法获取宽高，高度在某些带虚拟按键的设备上可能不准确
     * 此方法获取的高度为包含虚拟导航按键的高度，即使在虚拟导航栏被隐藏的情况下
     *
     * @param context 页面上下文
     * @return 屏幕宽高
     */
    private static Pair<Integer, Integer> getScreenSize(Context context) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        return new Pair<>(metrics.widthPixels, metrics.heightPixels);
    }

    /**
     * 获取屏幕宽
     *
     * @param activity 当前页面
     * @return 屏幕宽度
     */
    public static int getScreenWidth(Activity activity) {
        Display display = activity.getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size.x;
    }

    /**
     * 获取屏幕宽
     *
     * @param context 页面上下文
     */
    public static int screenWidth(Context context) {
        return context.getResources().getDisplayMetrics().widthPixels;
    }

    /**
     * 在华为平板上 这个方法在虚拟按键设置为可隐藏时，获取的是真实的高度（即可视区域的高度）。
     * 测试结果为，在虚拟导航栏可被隐藏的情况下，若隐藏，此方法获取整个屏幕高度，若显示则获取减去虚拟导航栏的高度
     *
     * @param activity 当前页面
     * @return 屏幕高度
     */
    public static int getScreenHeight(Activity activity) {
        Display display = activity.getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size.y;
    }

    /**
     * 获取屏幕高 这种方式在虚拟导航栏可被隐藏并隐藏时，获取的仍是减去了虚拟导航栏高度的宽
     * 故推荐使用 {@link #getScreenHeight}的方式
     *
     * @param context 页面上下文
     * @return int 屏幕高
     */
    public static int screenHeight(Context context) {
        return context.getResources().getDisplayMetrics().heightPixels;
    }

    /**
     * 此方法同上 ，故推荐使用 {@link #getScreenHeight}的方式
     *
     * @param windowManager 页面 windowManager
     * @return 屏幕高
     */
    public static int getScreenRealHeight(WindowManager windowManager) {
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        display.getRealMetrics(dm);
        return dm.heightPixels;
    }

    /**
     * @return 0 32位；1 64位
     */
    public static int getCpuType() {
        return isCPU64() ? 1 : 0;
    }

    /**
     * 获取设备是否为64位
     */
    public static boolean isCPU64() {
        boolean result = false;
        try {
            String mProcessor = getFieldFromCpuinfo("Processor");
            if (mProcessor != null) {
                // D/CpuUtils: isCPU64 mProcessor = AArch64 Processor rev 4 (aarch64)
                Log.d(TAG, "isCPU64 mProcessor = " + mProcessor);
                //list =  Arrays.asList(mProcessor.split("\\s"));
                if (mProcessor.contains("aarch64")) {
                    result = true;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return result;
    }


    /*  cat /proc/cpuinfo

        processor       : 0
        Processor       : AArch64 Processor rev 4 (aarch64)
        model name      : AArch64 Processor rev 4 (aarch64)
        BogoMIPS        : 26.00
        Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32
        CPU implementer : 0x41
        CPU architecture: 8
        CPU variant     : 0x0
        CPU part        : 0xd03
        CPU revision    : 4
    */
    public static String getFieldFromCpuinfo(String field) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("/proc/cpuinfo"));
        Pattern p = Pattern.compile(field + "\\s*:\\s*(.*)");

        try {
            String line;
            while ((line = br.readLine()) != null) {
                Matcher m = p.matcher(line);
                if (m.matches()) {
                    return m.group(1);
                }
            }
        } finally {
            br.close();
        }

        return null;
    }

    /**
     * 获取view顶部相对于屏幕的距离
     *
     * @param view
     * @return
     */
    public static int getViewTopInScreen(View view) {
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        int x = location[0]; // view距离 屏幕左边的距离（即x轴方向）
        int y = location[1]; // view距离 屏幕顶边的距离（即y轴方向）
        return y;
    }

    /**
     * 如果高/宽小于1.25，则视为折叠屏
     *
     * @param context
     * @return
     */
    public static boolean isFoldDevice(Context context) {
        float heightWidthRatio = screenHeight(context) * 1.0f / screenWidth(context);
        return heightWidthRatio > 0.741 && heightWidthRatio < 1.35f;
    }

    public static synchronized String getBrand() {
        String brand = "";
        String model = "";
        try {
            // 手机品牌
            brand = Build.BRAND;
            // 型号
            model = Build.MODEL;
            if (model != null) {
                model = model.trim().replaceAll("\\s*", "");
            } else {
                model = "";
            }
            return brand;
        } catch (Exception e) {
            e.printStackTrace();
            return brand;
        }
    }

    public static synchronized String getModel() {

        String brand = "";
        String model = "";
        try {
            // 手机品牌
            brand = Build.BRAND;
            // 型号
            model = Build.MODEL;
            if (model != null) {
                model = model.trim().replaceAll("\\s*", "");
            } else {
                model = "";
            }
            return model;
        } catch (Exception e) {
            e.printStackTrace();
            return model;
        }

    }
}
